<?php

namespace controller\admin;

defined('IA_ROOT') || exit();

use facade\Model;
use facade\View;
use facade\Util;

// 媒体管理
class Media extends Base
{
    // 媒体列表
    public function index()
    {
        if (Util::isAjax()) {
            $param = Util::param();
            $start = ($param['page'] - 1) * $param['limit'];
            $limit = $param['limit'];
            // $where = "`id` <= (SELECT `id` FROM `media` ORDER BY `id` DESC LIMIT $start, 1)";
            $where = "1 = 1";
            // 搜索
            if (!empty($param['search'])) {
                foreach ((array)$param['search'] as $k => $v) {
                    if (strlen($v)) {
                        if (in_array($k, ['type', 'ext', 'status'])) {
                            $where .= " AND `$k` = '$v'";
                        } else if (in_array($k, ['start', 'end'])) {
                            $timestamp = strtotime($v);
                            if ($k == 'start')
                                $where .= " AND `create_at` >= '$timestamp'";
                            else
                                $where .= " AND `create_at` <= '$timestamp'";
                        } else {
                            $where .= " AND `$k` like '%{$v}%'";
                        }
                    }
                }
            }
            $count = Model::fetchColumn("SELECT COUNT(*) FROM `media` WHERE $where ORDER BY `id` DESC");
            $data = Model::fetchAll("SELECT * FROM `media` WHERE $where ORDER BY `id` DESC LIMIT $start, $limit");
            if ($count) {
                $res['code'] = 0;
            } else {
                $res['code'] = 1;
                $res['msg'] = Util::tran('暂无记录');
            }
            $res['count'] = $count;
            $res['data'] = array_map(function ($item) {
                $item['url'] = '';
                $item['preview'] = '';
                if (is_file(str_replace('\\', DIRECTORY_SEPARATOR, IA_ROOT . $item['path']))) {
                    $item['url'] = Util::url('/') . ltrim($item['path'], '/');
                    $item['size'] = round(filesize(str_replace('\\', DIRECTORY_SEPARATOR, IA_ROOT . $item['path'])) / 1024 * 100) / 100;
                    if (preg_match('#/static/upload/.+?\.(gif|jpg|jpeg|png|bmp|webp|psd|svg|tiff)$#i', $item['path'])) {
                        $item['preview'] = '<img src="' . $item['url'] . '" style="width:50px;height:100%" alt="preview" />';
                    } else {
                        if ($ico = $this->ico($item['ext']))
                            $item['preview'] = '<img src="' . $ico . '" style="width:50px;height:100%" alt="preview" />';
                    }
                } else {
                    $item['size'] = 0;
                    $item['preview'] = '404 Err!';
                    $item['status'] = 2;
                }
                $item['time'] = date('Y-m-d H:i', $item['time']);
                return $item;
            }, $data);
            exit(json_encode($res));
        }
        // 系统设置
        View::assign(['setting' => $this->setting, 'exts' => array_filter(explode('|', $this->setting['upload_type']))]);
        View::assign('tran', [
            'file_name' => Util::tran('文件名'),
            'input' => Util::tran('请输入'),
            'choose' => Util::tran('请选择'),
            'type' => Util::tran('类型'),
            'picture' => Util::tran('图片'),
            'media' => Util::tran('音视频'),
            'file' => Util::tran('文件'),
            'ext_name' => Util::tran('扩展名'),
            'status' => Util::tran('状态'),
            'normal' => Util::tran('正常'),
            'unused' => Util::tran('未使用'),
            'invalid' => Util::tran('失效'),
            'date' => Util::tran('日期'),
            'delall' => Util::tran('批量删除'),
            'upload' => Util::tran('上传'),
            'upload_success' => Util::tran('上传成功'),
            'refresh' => Util::tran('刷新'),
            'calc_file' => Util::tran('计算孤立文件'),
            'media_list' => Util::tran('媒体列表'),
            'preview' => Util::tran('预览'),
            'size' => Util::tran('大小'),
            'url' => Util::tran('路径'),
            'time' => Util::tran('时间'),
            'option' => Util::tran('操作'),
            'download' => Util::tran('下载'),
            'rename' => Util::tran('重命名'),
            'delete' => Util::tran('删除'),
            'info' => Util::tran('信息'),
            'drag_or_upload' => Util::tran('点击上传，或将文件拖拽到此处'),
        ]);
        View::display('admin/media/index.html');
    }

    // 上传文件
    public function file()
    {
        View::assign('setting', $this->setting);
        View::assign('tran', [
            'upload' => Util::tran('上传'),
            'choice_multi_file' => Util::tran('选择多文件'),
            'file_name' => Util::tran('文件名'),
            'preview' => Util::tran('预览'),
            'size' => Util::tran('大小'),
            'status' => Util::tran('状态'),
            'option' => Util::tran('操作'),
            'delete' => Util::tran('删除'),
            'start_upload' => Util::tran('开始上传'),
            'await_upload' => Util::tran('等待上传'),
            're_upload' => Util::tran('重新上传'),
            'upload_success' => Util::tran('上传成功'),
            'upload_fail' => Util::tran('上传失败'),
        ]);
        View::display('admin/media/file.html');
    }

    // 允许上传
    public function upload()
    {
        if (Util::isAjax() || Util::isPost()) {
            $file = Util::isAjax() ? $_FILES['file'] : $_FILES['imgFile'];
            $errMsg = [
                0 => Util::tran('上传完成'),
                1 => Util::tran('超过的单文件大小'),
                2 => Util::tran('超过前端表单限制'),
                3 => Util::tran('上传文件不完整'),
                4 => Util::tran('没有文件被上传'),
                5 => Util::tran('系统保留'),
                6 => Util::tran('找不到临时目录'),
                7 => Util::tran('目标没有写入权限'),
            ];
            if ($file['error']) {
                // 静默删除可能存在的临时文件
                $file['tmp_name'] && @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                if (Util::isAjax())
                    Util::errMsg($errMsg[$file['error']]);
                else
                    exit(json_encode(['error' => 1, 'message' => $errMsg[$file['error']]]));
            }
            $path_parts = pathinfo($file['name']);
            // $name = Util::uniqidReal();
            list($usec, $sec) = explode(" ", microtime());
            $name = date("YmdHis") . str_pad(round($usec * 1000), 3, '0', STR_PAD_RIGHT);
            $ext = $path_parts['extension'];
            $size = round($file['size'] / 1024 * 100) / 100;
            // 验证扩展名
            if (!$ext || !in_array($ext, array_filter(explode('|', $this->setting['upload_type'])))) {
                // 静默删除临时文件
                @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                if (Util::isAjax())
                    Util::errMsg(['msg' => Util::tran('不允许的上传类型') . ' ' . $ext]);
                else
                    exit(json_encode(['error' => 1, 'message' => Util::tran('不允许的上传类型') . ' ' . $ext]));
            }
            // 验证大小
            if ($size > $this->setting['upload_size']) {
                // 静默删除临时文件
                @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                if (Util::isAjax())
                    Util::errMsg(Util::tran('文件大小不能超过') . ' ' . $this->setting['upload_size'] . 'KB');
                else
                    exit(json_encode(['error' => 1, 'message' => Util::tran('文件大小不能超过') . ' ' . $this->setting['upload_size'] . 'KB']));
            }
            // 媒体归类
            $exts = array(
                'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp', 'psd', 'svg', 'tiff'),
                'flash' => array('swf', 'flv'),
                'media' => array('mp3', 'mp4', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'),
                'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2'),
            );
            $type = false;
            $folder = '';
            if (in_array($ext, $exts['image'])) {
                // 图片归类
                $type = 0;
                $folder = 'image';
            } else if (in_array($ext, $exts['media'])) {
                // 音视频归类
                $type = 1;
                $folder = 'media';
            } else if (in_array($ext, $exts['flash'])) {
                // Flash归类
                $type = 2;
                $folder = 'flash';
            } else if (in_array($ext, $exts['file'])) {
                // 文件类型
                $type = 3;
                $folder = 'file';
            }
            // 未知类型
            if ($type === false || $folder === '') {
                // 静默删除临时文件
                @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                if (Util::isAjax())
                    Util::errMsg(['code' => 1, 'msg' => Util::tran('未知的文件类型')]);
                else
                    exit(json_encode(['error' => 1, 'message' => Util::tran('未知的文件类型')]));
            }
            $status = 1;
            $time = time();
            $year = date('Y');
            $path = "/static/upload/{$folder}/{$year}/{$name}.{$ext}";
            // 递归创建目录
            !is_dir(IA_ROOT . "/static/upload/{$folder}/{$year}/") && mkdir(IA_ROOT . "/static/upload/{$folder}/{$year}/", 0700, true);
            // 检查重复文件
            if ($target = $this->checkDuplicate(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']), IA_ROOT . "/static/upload/{$folder}")) {
                // 静默删除临时文件
                @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                if (Util::isAjax())
                    Util::errMsg(['code' => 1, 'msg' => Util::tran('发现重复') . '：' . str_replace(IA_ROOT, '', $target)]);
                else
                    exit(json_encode(['error' => 1, 'message' => Util::tran('发现重复') . '：' . str_replace(IA_ROOT, '', $target)]));
            }
            // 压缩图片（gif不压缩）
            if ($type === 0 && in_array($ext, ['jpg', 'jpeg', 'png', 'bmp', 'wbmp'])) {
                require_once IA_ROOT . '/util/imgcompress.php';
                $percent = 1;
                list($width) = getimagesize(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                if ($width > 718) {
                    $percent = 718 / $width;
                }
                (new \imgcompress(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']), $percent))->compressImg(IA_ROOT . $path);
                if (!is_file(IA_ROOT . $path)) {
                    // 静默删除临时文件
                    @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                    if (Util::isAjax())
                        Util::errMsg(['code' => 1, 'msg' => Util::tran('图片压缩失败')]);
                    else
                        exit(json_encode(['error' => 1, 'message' => Util::tran('图片压缩失败')]));
                }
                // 检查压缩图片重复
                if ($target = $this->checkDuplicate(IA_ROOT . $path, IA_ROOT . "/static/upload/{$folder}")) {
                    // 静默删除临时文件
                    @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                    @unlink(IA_ROOT . $path);
                    if (Util::isAjax())
                        Util::errMsg(['code' => 1, 'msg' => Util::tran('发现重复') . '：' . str_replace(IA_ROOT, '', $target)]);
                    else
                        exit(json_encode(['error' => 1, 'message' => Util::tran('发现重复') . '：' . str_replace(IA_ROOT, '', $target)]));
                }
            } else {
                // 移动临时文件
                if (!@move_uploaded_file(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']), IA_ROOT . $path)) {
                    // 静默删除临时文件
                    @unlink(str_replace('\\', DIRECTORY_SEPARATOR, $file['tmp_name']));
                    if (Util::isAjax())
                        Util::errMsg(['code' => 1, 'msg' => Util::tran('移动文件失败')]);
                    else
                        exit(json_encode(['error' => 1, 'message' => Util::tran('移动文件失败')]));
                }
            }
            // 写入数据库记录日志
            $lastInsertId = Model::insert('media', compact('name', 'ext', 'path', 'type', 'status', 'time'));
            if ($lastInsertId) {
                $this->log(Util::tran('上传文件'), Util::tran('上传文件') . " {$path} " . Util::tran('成功'), 0);
                $url = Util::url('/') . ltrim($path, '/');
                if (Util::isAjax())
                    Util::errMsg(['code' => 0, 'msg' => Util::tran('上传文件成功'), 'data' => ['src' => $path, 'title' => $name], 'files' => ['file' => $url]]);
                else
                    exit(json_encode(['error' => 0, 'url' => $path]));
            } else {
                $this->log(Util::tran('上传文件'), Util::tran('上传文件') . " {$path} " . Util::tran('失败'), 1);
                if (Util::isAjax())
                    Util::errMsg(['code' => 1, 'msg' => Util::tran('上传文件失败')]);
                else
                    exit(json_encode(['error' => 1, 'message' => Util::tran('上传文件失败')]));
            }
            exit();
        }
    }

    // 计算孤立文件
    public function calc()
    {
        $paths = [];
        // User 中引用的文件
        $rows = Model::fetchAll("SELECT `avatar` FROM `user` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            if (preg_match('#^/static/upload/.+?#i', $row['avatar'])) {
                $paths[] = trim($row['avatar']);
            }
        }

        // Category 中引用的文件
        $rows = Model::fetchAll("SELECT `cover` FROM `category` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            if (preg_match('#^/static/upload/.+?#i', $row['cover'])) {
                $paths[] = trim($row['cover']);
            }
        }

        // Article 中引用的文件
        $ids = [];
        $rows = Model::fetchAll("SELECT `id` FROM `article` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $ids[] = $row['id'];
        }
        // 每次100条记录分批遍历
        $i = 0;
        while ($idArr = array_slice($ids, $i, 100)) {
            $idStr = implode(',', $idArr);
            $rows = Model::fetchAll("SELECT `cover`, `content` FROM `article` WHERE `id` IN ($idStr) ORDER BY `id` DESC");
            foreach ($rows as $row) {
                if (preg_match('#^/static/upload/.+?#i', $row['cover'])) {
                    $paths[] = trim($row['cover']);
                }
                // 内容图片遍历
                if (preg_match_all('#<[^>]*[href|src]=["\'](/static/upload/.+?)["\'][^>]*>#i', $row['content'], $matches)) {
                    $paths = array_merge($paths, array_map('trim', $matches[1]));
                }
            }
            $i += 100;
        }

        // Page 中引用的文件
        $rows = Model::fetchAll("SELECT `cover`, `content` FROM `page` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            if (preg_match('#^/static/upload/.+?#i', $row['cover'])) {
                $paths[] = trim($row['cover']);
            }
            // 内容图片遍历
            if (preg_match_all('#<[^>]*[href|src]=["\'](/static/upload/.+?)["\'][^>]*>#i', $row['content'], $matches)) {
                $paths = array_merge($paths, array_map('trim', $matches[1]));
            }
        }

        // Link 中引用的文件
        $rows = Model::fetchAll("SELECT `logo` FROM `link` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            if (preg_match('#^/static/upload/.+?#i', $row['logo'])) {
                $paths[] = trim($row['logo']);
            }
        }

        // Comment 中引用的文件
        $ids = [];
        $rows = Model::fetchAll("SELECT `id` FROM `comment` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $ids[] = $row['id'];
        }
        // 每次100条记录分批遍历
        $i = 0;
        while ($idArr = array_slice($ids, $i, 100)) {
            $idStr = implode(',', $idArr);
            $rows = Model::fetchAll("SELECT `comment` FROM `comment` WHERE `id` IN ($idStr) ORDER BY `id` DESC");
            foreach ($rows as $row) {
                // 内容图片遍历
                if (preg_match_all('#<[^>]*[href|src]=["\'](/static/upload/.+?)["\'][^>]*>#i', $row['comment'], $matches)) {
                    $paths = array_merge($paths, array_map('trim', $matches[1]));
                }
            }
            $i += 100;
        }

        // Setting 中引用的文件
        $rows = Model::fetchAll("SELECT `value` FROM `setting` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $values = json_decode($row['value'], true);
            if ($values) {
                foreach ($values as $value) {
                    if (preg_match('#^/static/upload/.+?#i', $value)) {
                        $paths[] = trim($value);
                    }
                }
            }
        }

        // 去重整理
        $paths = array_unique($paths);
        $ids = [];
        $rows = Model::fetchAll("SELECT `id` FROM `media` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $ids[] = $row['id'];
        }
        // 每次100条记录分批遍历
        $i = 0;
        $stat = [0 => 0, 1 => 0, 2 => 0];
        while ($arr = array_slice($ids, $i, 100)) {
            $idArr = [0 => [], 1 => [], 2 => []];
            $idStr = implode(',', $arr);
            $rows = Model::fetchAll("SELECT `id`, `path` FROM `media` WHERE `id` IN ($idStr) ORDER BY `id` DESC");
            foreach ($rows as $row) {
                if (!is_file(IA_ROOT . $row['path'])) {
                    // 失效文件
                    $idArr[2][] = $row['id'];
                } else {
                    if (in_array($row['path'], $paths)) {
                        // 在用文件
                        $idArr[0][] = $row['id'];
                    } else {
                        // 未使用文件
                        $idArr[1][] = $row['id'];
                    }
                }
            }
            // 更新媒体状态
            $idArr[1] && Model::update('media', ['status' => 1], ['id' => $idArr[1]]);
            $idArr[0] && Model::update('media', ['status' => 0], ['id' => $idArr[0]]);
            $idArr[2] && Model::update('media', ['status' => 2], ['id' => $idArr[2]]);
            $stat[0] += count($idArr[0]);
            $stat[1] += count($idArr[1]);
            $stat[2] += count($idArr[2]);
            $i += 100;
        }
        $this->log(Util::tran('计算孤立文件'), Util::tran('共找到文件：') . "{$stat[0]} " . Util::tran('个在用，') . "{$stat[1]} " . Util::tran('个未使用，') . "{$stat[2]} " . Util::tran('个无效'), 0);
        exit(json_encode(['code' => 0, 'msg' => Util::tran('共找到文件：') . "{$stat[0]} " . Util::tran('个在用，') . "{$stat[1]} " . Util::tran('个未使用，') . "{$stat[2]} " . Util::tran('个无效')]));
    }

    // 检查文件状态
    private function checkFileStatus($path)
    {
        // User 中引用的文件
        $rows = Model::fetchAll("SELECT `avatar` FROM `user` WHERE `avatar` = '$path' ORDER BY `id` DESC");
        if ($rows) return true;

        // Category 中引用的文件
        $rows = Model::fetchAll("SELECT `cover` FROM `category` WHERE `cover` = '$path' ORDER BY `id` DESC");
        if ($rows) return true;

        // Article 中引用的文件
        $ids = [];
        $rows = Model::fetchAll("SELECT `id` FROM `article` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $ids[] = $row['id'];
        }
        // 每次100条记录分批遍历
        $i = 0;
        while ($idArr = array_slice($ids, $i, 100)) {
            $idStr = implode(',', $idArr);
            $rows = Model::fetchAll("SELECT `cover` FROM `article` WHERE `id` IN ($idStr) AND `cover` = '$path' ORDER BY `id` DESC");
            if ($rows) return true;
            $rows = Model::fetchAll("SELECT `content` FROM `article` WHERE `id` IN ($idStr) AND `content` LIKE '%{$path}%' ORDER BY `id` DESC");
            if ($rows) return true;
            $i += 100;
        }

        // Page 中引用的文件
        $rows = Model::fetchAll("SELECT `cover` FROM `page` WHERE `content` LIKE '%{$path}%' ORDER BY `id` DESC");
        if ($rows) return true;
        $rows = Model::fetchAll("SELECT `content` FROM `page` WHERE `content` LIKE '%{$path}%' ORDER BY `id` DESC");
        if ($rows) return true;

        // Link 中引用的文件
        $rows = Model::fetchAll("SELECT `logo` FROM `link` WHERE `logo` = '$path' ORDER BY `id` DESC");
        if ($rows) return true;

        // Comment 中引用的文件
        $ids = [];
        $rows = Model::fetchAll("SELECT `id` FROM `comment` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $ids[] = $row['id'];
        }
        // 每次100条记录分批遍历
        $i = 0;
        while ($idArr = array_slice($ids, $i, 100)) {
            $idStr = implode(',', $idArr);
            $rows = Model::fetchAll("SELECT `comment` FROM `comment` WHERE `id` IN ($idStr) AND `comment` LIKE '%{$path}%' ORDER BY `id` DESC");
            if ($rows) return true;
            $i += 100;
        }

        // Setting 中引用的文件
        $rows = Model::fetchAll("SELECT `value` FROM `setting` ORDER BY `id` DESC");
        foreach ($rows as $row) {
            $values = json_decode($row['value'], true);
            if ($values) {
                foreach ($values as $value) {
                    if ($path == $value) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    // 检查上传内容重复
    private function checkDuplicate($filePath, $directory)
    {
        $files = scandir($directory);
        foreach ($files as $file) {
            if ($file === '.' || $file === '..') {
                continue;
            }
            $path = $directory . '/' . $file;
            if (is_dir($path)) {
                $result = $this->checkDuplicate($filePath, $path);
                if ($result !== false) {
                    return $result;
                }
            } else {
                if ($path !== $filePath && md5_file($path) === md5_file($filePath)) {
                    return $path;
                }
            }
        }
        return false;
    }

    // 重命名
    public function rename()
    {
        $param = Util::param(['id', 'field', 'value']);
        empty($param['id']) && Util::errMsg('ID ' . Util::tran('错误'));
        $row = Model::fetch("SELECT * FROM `media` WHERE `id`=:id", [':id' => $param['id']]);
        !$row && Util::errMsg('ID ' . Util::tran('非法'));
        // 检查文件状态
        $fileStatus = $this->checkFileStatus($row['path']);
        if ($fileStatus) {
            Model::update('media', ['status' => 0], ['id' => $param['id']]);
            $row['status'] = 0;
        }
        (empty($param['field']) || !in_array($param['field'], ['name'])) && Util::errMsg(Util::tran('非法字段'));
        $row['status'] != 1 && Util::errMsg(Util::tran('文件有在使用或已失效'));

        // 验证字段
        if ($param['field'] == 'name') {
            empty($param['value']) && Util::errMsg(Util::tran('文件名不能为空'));
            $check = Model::fetchColumn("SELECT `path` FROM `media` WHERE `name`=:name ORDER BY `id`", [':name' => $param['value']]);
            $check && $check != $row['path'] && Util::errMsg(Util::tran('文件重名'));
        }

        // 重命名
        $path_parts = pathinfo($row['path']);
        $new_path = $path_parts['dirname'] . '/' . $param['value'] . '.' . $row['ext'];
        !is_file(IA_ROOT . $row['path']) && Util::errMsg(Util::tran('文件不存在'));
        !rename(IA_ROOT . $row['path'], IA_ROOT . $new_path) && Util::errMsg(Util::tran('重命名失败'));

        // 更新数据库记录日志
        $rowCount = Model::update('media', [$param['field'] => $param['value'], 'path' => $new_path], ['id' => $param['id']]);
        if ($rowCount) {
            $this->log(Util::tran('重命名'), Util::tran('重命名') . " {$param['field']}: {$row[$param['field']]} -> {$param['value']} " . Util::tran('成功'), 0);
            Util::errMsg(['code' => 0, 'msg' => Util::tran('重命名成功')]);
        } else {
            $this->log(Util::tran('重命名'), Util::tran('重命名') . " {$param['field']}: {$row[$param['field']]} -> {$param['value']} " . Util::tran('失败'), 1);
            Util::errMsg(['code' => 1, 'msg' => Util::tran('重命名失败')]);
        }
    }

    // 删除
    public function delete()
    {
        $param = Util::param(['id']);
        (empty($param) || !isset($param['id'])) && Util::errMsg(Util::tran('请选择数据'));
        $ids = (array)$param['id'];
        $ids = array_unique($ids);
        $ids = implode(',', $ids);
        $files = Model::fetchAll("SELECT `id`, `name`, `path`, `status` FROM `media` WHERE `id` IN ($ids) ORDER BY `id` DESC");
        $count = count($files);
        $i = 0;
        $ids = [];
        $names = [];
        foreach ($files as $file) {
            // 检查文件引用状态
            $fileStatus = $this->checkFileStatus($file['path']);
            if ($fileStatus && $file['status'] > 0) {
                Model::update('media', ['status' => 0], ['id' => $file['id']]);
                $file['status'] = 0;
            }
            // 孤立和失效文件
            if ($file['status'] > 0) {
                $i++;
                $ids[] = $file['id'];
                $names[] = $file['name'];
                $realpath = IA_ROOT . $file['path'];
                // 删除硬盘文件
                is_file($realpath) && @unlink($realpath);
            }
        }

        // 删除数据记录日志
        Model::delete('media', ['id' => $ids]);
        if ($i == $count) {
            $this->log(Util::tran('删除文件'), Util::tran('删除文件') . " " . implode(' ', $names) . " " . Util::tran('成功'), 0);
            Util::errMsg(['code' => 0, 'msg' => Util::tran('删除成功')]);
        } else if ($i == 0) {
            $this->log(Util::tran('删除文件'), Util::tran('删除文件失败，文件有在使用'), 1);
            Util::errMsg(['code' => 1, 'msg' => Util::tran('文件有在使用，删除失败！')]);
        } else {
            $this->log(Util::tran('删除文件'), Util::tran('删除文件') . " " . implode(' ', $names) . " " . Util::tran('成功') . "，" . ($count - $i) . Util::tran('个文件有在使用'), 0);
            Util::errMsg(['code' => 0, 'msg' => Util::tran('共删除') . $i . Util::tran('个文件') . '，' . ($count - $i) . Util::tran('个文件有在使用')]);
        }
    }
}
